package com.sxj.corejava.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author 石小俊
 * 日期工具类
 */
public class DateUtil {


    /**
     * 将日期转换成字符串,需要指定转换成的字符串格式
     * @param date    需要转换的日期值
     * @param pattern 转换后的日期格式
     * @return 返回转换后的字符串
     */
    public static String toString(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }

    /**
     * 将日期转换成一个默认格式的字符串
     * @param date 需要转换的日期值
     * @return 转换后的日期
     * @see DateConstant
     */
    public static String toString(Date date) {
        return toString(date, DateConstant.DATE_DEFAULT_PATTERN);
    }

    /**
     * 将一个指定格式的字符串转换成日期
     * @param str     需要转换的字符串
     * @param pattern 指定的格式
     * @return 转换后的日期
     */
    public static Date toDate(String str, String pattern) throws ParseException {
        return new SimpleDateFormat(pattern).parse(str);
    }

    /**
     * 将一个默认格式的字符串转换成日期
     * @param str 需要转换的字符串
     * @return 转换后的日期
     * @see DateConstant
     */
    public static Date toDate(String str) throws ParseException {
        return toDate(str, DateConstant.DATE_DEFAULT_PATTERN);
    }

    /**
     * 计算指定日期的前一天
     * @param date
     * @return
     */
    public static Date getYesterday(Date date) {
        long time = date.getTime() - DateConstant.ONE_DAY_MILLISECOND;
        return new Date(time);
    }

    /**
     * 计算指定日期的下一天
     * @param date
     * @return
     */
    public static Date getNextDay(Date date) {
        return new Date(date.getTime() + DateConstant.ONE_DAY_MILLISECOND);
    }


    /**
     * 计算两个日期之间相差的天数
     * 不足一天的直接舍去
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getDuringDay(Date startDate, Date endDate) {
        // 计算两个日期之间相差的毫秒数
        long time = endDate.getTime() - startDate.getTime();
        // 计算这个毫秒数表示多少天,取商即可
        int day = (int) (time / DateConstant.ONE_DAY_MILLISECOND);
        return day;
    }

    /**
     * 计算两个日期之间相差的天数
     * 不足一天按一天算
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getDuringDay2(Date startDate, Date endDate) {
        // 定义一个用于接收相差天数的变量
        int day = 0;
        // 只要startDate在endDate之前,每一次将startDate的值取下一天
        // 一直到超过endDate为止
        while (startDate.before(endDate)) {
            // 每次进来,说明相差天数值+1
            day++;
            // 将startDate的值变为下一天
            startDate = getNextDay(startDate);
        }
        return day;
    }

    /**
     * 获取默认格式的日期中指定的年、月、日、时、分、秒的值
     * 对应字段可以设置为常量
     * @param date  日期值
     * @param field 需要获取的字段是谁
     * @return 根据传递的参数不同, 返回日期中不同部分的值
     * @see DateConstant
     */
    public static int getField(Date date, int field) {
        // 将日期值转换成字符串类型
        // 默认日期格式为:yyyy-MM-dd HH:mm:ss
        String s = toString(date);
        // 此时可以通过正则表达式将日期的年月日时分秒分割成数组的元素
        // field的值即为数组的下标
        String[] arr = s.split("-|\\s|:");
        return Integer.parseInt(arr[field]);
    }

    /**
     * 根据给定的年份与月份获取这个月共有多少天
     * 通过日历对象提供的方法实现
     * @param year
     * @param month
     * @return
     */
    public static int getDay(int year, int month) {
        // 定义一个日历对象
        Calendar calendar = Calendar.getInstance();
        // 将该日历对象的年份与月份设置为year与month
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        return calendar.getActualMaximum(Calendar.DATE);
    }

    /**
     * 根据给定的年份与月份获取这个月共有多少天
     * 通过日期的运算实现
     * @param year
     * @param month
     * @return
     */
    public static int getDay2(int year, int month) {
        // 想要获取year年month月共有多少天
        // 可以将日历对象的值设置为year年month月的最后一天
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        // 设置下一个月的第一天的前一天
        // 这一天即为本月最后一天
        // 下个月
        // calendar.set(Calendar.MONTH,month - 1 + 1);
        calendar.set(Calendar.MONTH, month);
        // 第一天的前一天
        // calendar.set(Calendar.DATE,1 - 1);
        calendar.set(Calendar.DATE, 0);
        return calendar.get(Calendar.DATE);
    }

    public static void main(String[] args) throws ParseException {
        Date date = new Date();
        System.out.println(toString(date));
        System.out.println(toString(date, "yyyy年MM月dd日 HH:mm:ss"));

        System.out.println(toDate("2025-07-28 13:39:37", "yyyy-MM-dd HH:mm:ss"));
        System.out.println(toDate("2025年07月28日 13:39:37", "yyyy年MM月dd日 HH:mm:ss"));
        Date yesterday = getYesterday(date);
        System.out.println(toString(yesterday));
        System.out.println(toString(getNextDay(date)));

        Date endDate = new Date(2025 - 1900, 9 - 1, 10);
        System.out.println(getDuringDay(date, endDate));
        System.out.println(getDuringDay2(date, endDate));

        System.out.println(getField(date, DateConstant.YEAR) + "年");
        System.out.println(getField(date, DateConstant.MONTH) + "月");
        System.out.println(getField(date, DateConstant.DAY) + "日");
        System.out.println(getField(date, DateConstant.HOURS) + "时");
        System.out.println(getField(date, DateConstant.MINUTE) + "分");
        System.out.println(getField(date, DateConstant.SECOND) + "秒");
    }

}
